﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Mighty.Common;
using System.Collections;

namespace Mighty.Brain
{
    public class StreetBrain : BasicBrain
    {
        public override Betting BettingTicEvent()
        {
            Betting betting = new Betting();
            betting.isPass = true;

            // 각 무늬의 개수를 센다
            int heart = 0;
            int clover = 0;
            int spade = 0;
            int diamond = 0;
            int acee = 0;
            int[] ace = new int[4];
            for (int i = 0; i < 10; i++)
            {
                HandedCard card = gameInfo.myCards[i];
                if (card.shape == Shape.Clover) clover++;
                else if (card.shape == Shape.Heart) heart++;
                else if (card.shape == Shape.Spade) spade++;
                else if (card.shape == Shape.Diamond) diamond++;

                if (card.number == 14)
                {
                    ace[(int)card.shape]++;
                    acee++;
                }
               
            }

            // 가장 많은 무늬를 찾아 낸다
            Giruda selectedShape = Giruda.Heart;
            int selectedCount = heart;

            if (clover > selectedCount)
            {
                selectedShape = Giruda.Clover;
                selectedCount = clover;
            }
            if (spade > selectedCount)
            {
                selectedShape = Giruda.Spade;
                selectedCount = spade;
            }
            if (diamond > selectedCount)
            {
                selectedShape = Giruda.Diamond;
                selectedCount = diamond;
            }


            int limit = 13;

            if (ace[(int)selectedShape] + acee >= 3) limit += 2;
            else if (ace[(int)selectedShape] >= 1) limit += 1;

            if (gameInfo.betting.limit > 0)
            {

                Betting previousBetting = (Betting)gameInfo.bettingHistory[gameInfo.bettingHistory.Count - 1];
                if (previousBetting.limit <= 15 && previousBetting.limit+1 <= limit)
                {
                    betting.isPass = false;
                    betting.limit = previousBetting.limit + 1;
                }

            }
            else
            {
                betting.isPass = false;
                betting.limit = 13;
            }
            return betting;        
        }

        //주공시 3장 더 받은카드 포함하여 버릴카드 3장 선택하기( 기루다가 아닌무늬중 작은 숫자부터 버리며 버린카드가 3장이 되면 break )
        public override HandedCard[] ChoiceCardEvent()
        {
            int discardCnt = 0;
            
            for (int n = 2 ; n < 13 ; n++ ) 
            {
                for (int i = 0; i <= 12; i++)
                {
                    if (gameInfo.myCards[i].shape != (Shape)gameInfo.betting.giruda)
                    {
                        if (gameInfo.myCards[i].number == n)
                        {
                            gameInfo.myCards[i].cmdRemove = true;
                            discardCnt++;
                        }
                    }
                    if ( discardCnt == 3 ) break;
                }
                if ( discardCnt == 3 ) break;
            }
            return gameInfo.myCards;
        }

        //마지막 베팅 설정(변경 사항 없음)
        public override Betting LastBettingEvent()
        {
            return gameInfo.betting;
        }


        public override FriendPlayer ChoiceFriendEvent()
        {
            int i = 0;
            int m = 0;
            int j = 0;
            for (i = 0; i <= 9; i++)
            {
                if (gameInfo.myCards[i].IsSame(gameInfo.mighty))
                {
                    m = 1;
                }
            }
            for (i = 0; i <= 9; i++)
            {
                if (gameInfo.myCards[i].shape == Shape.Joker)
                {
                    j = 1;
                }
            }

            if (m == 1)
            {
                if (j == 1)
                {
                    gameInfo.friend.howToSelect = FriendPlayer.HowToSelect.firstwin;
                }
                else
                {
                    gameInfo.friend.howToSelect = FriendPlayer.HowToSelect.card;
                    gameInfo.friend.cardCondition = new Card(Shape.Joker, 0);
                }
            }
            else
            {
                gameInfo.friend.howToSelect = FriendPlayer.HowToSelect.card;
                gameInfo.friend.cardCondition = gameInfo.mighty;
            }

            return gameInfo.friend;
        }

        

           // <summary>
        // 카드낼차례
        //  * 각 사용자의 턴에 한번씩 호출되며 낼 카드를 결과값으로 리턴해야 한다. 
        //  * 사용가능한 카드에는 myCards[i].isPossible 속성이 true로 설정되어 있다. 
        //  * 만약 사용불가능한 카드를 낼 경우에 시스템은 카드배열에서 제일 처음 만나는 사용가능한 카드를 골라서 사용한다
        // </summary>
        // <remarks>
        // [기본행동] 가능한 카드중에서 랜덤하게 하나의 카드를 선택한다
        // </remarks>
       
        
        public override HandedCard RoundTicEvent()
        {
            int stackmaxnumber;

            List<HandedCard> possibleCards = new List<HandedCard>();
            foreach (HandedCard card in gameInfo.myCards)
            {
                if (card.isPossible) possibleCards.Add((HandedCard)card.Clone());
            }

            ArrayList round_Cards = new ArrayList();

            Round r = gameInfo.roundHistory[gameInfo.roundIdx];

            int scoreCardCnt = 0;
            for (int i = 0; i < 5; i++)
            {
                RoundCard rc = r.cardStack[i];
                if (rc == null) break;

                if (rc.number > 9) scoreCardCnt++;

                //카드를 나온 카드 저장소에 넣는다
                round_Cards.Add(rc);

            }

            HandedCard joker = null;
            foreach (HandedCard card in gameInfo.myCards)
            {
                if (card.isPossible)
                {
                    if (card.shape == Shape.Joker) joker = card;
                    possibleCards.Add((HandedCard)card.Clone());
                }
            }



            if (gameInfo.roundCardIdx > 1)
            {
                if (r.cardStack[0].shape == Shape.Joker || r.cardStack[1].shape == Shape.Joker)
                    return (HandedCard)possibleCards[0];

                else if (scoreCardCnt > 1)
                {
                    if (joker != null) return joker;
                }

                stackmaxnumber = 0;

                for (int i = 0; i < possibleCards.Count - 1; i++)
                {
                    for (int j = i + 1; j < possibleCards.Count; j++)
                    {

                        int temp;
                        if (possibleCards[i].number > possibleCards[j].number)
                        {
                            temp = possibleCards[i].number;
                            possibleCards[i].number = possibleCards[j].number;
                            possibleCards[j].number = temp;
                        }
                    }
                }


                if (r.cardStack[0].number > r.cardStack[1].number)
                    stackmaxnumber = r.cardStack[0].number;
                else
                    stackmaxnumber = r.cardStack[1].number;

                for (int i = 2; i < 4; i++)
                {
                    if (r.cardStack[i] != null && r.cardStack[i].number > stackmaxnumber)
                    {
                        stackmaxnumber = r.cardStack[i].number;
                    }
                }
                for (int j = 0; j < possibleCards.Count; j++)
                {
                    if (stackmaxnumber < possibleCards[j].number)
                        return possibleCards[j];
                }
                return (HandedCard)possibleCards[0];
            }





            if (gameInfo.roundCardIdx == 0)
            {
                if (gameInfo.myInfo == gameInfo.attackPlayer)
                {
                    for (int i = 0; i < possibleCards.Count; i++)
                    {
                        if (((HandedCard)possibleCards[i]).shape == (Shape)gameInfo.betting.giruda)
                            return (HandedCard)possibleCards[i];
                    }
                    return (HandedCard)possibleCards[0];
                }
                return (HandedCard)possibleCards[10 - gameInfo.roundIdx];
            }




            else
            {
                if (r.cardStack[0].shape == Shape.Joker || r.cardStack[1].shape == Shape.Joker)
                    return (HandedCard)possibleCards[0];

                Random rndCard = new Random();
                int k = rndCard.Next(possibleCards.Count);

                return (HandedCard)possibleCards[k];
            }


        }
        
     }
}
